A view is a rectangular display object which provides visual presentation of data. Views are storable, and may be embedded recursively.
A view usually contain a Models.Model which represents some data, and a Controllers.Controller which provides interaction of the view with the user. There may be several views for each model simultaneously, but at most one controller per view.
If several views share the same model, every change of the model must cause all its views to update their contents accordingly. Module Models provides a messaging mechanism through which visible views can be notified of model modifications, and thus re-establish the display's consistency.
It is possible to implement views which do not contain a model. These views cannot use the messaging mechanism of module Models. Therefore, such views usually don't share data and are independent from each other.
It is also possible to implement views which do not contain a controller. This is possible because all messages to a controller are sent to the controller's view, not directly to the controller itself. Thus a view can decide whether to handle these messages itself, or whether to forward them to a controller. Simple views rarely contain a controller.
Because a view is an extension of a Stores.Store, it can be embedded in a model, such that it is externalized and internalized as part of this model. This makes it possible to realize compound documents, which contain views containing views containing views...
When a view needs to draw to the screen (or printer), it can do this through a frame. A frame is an access path to the port on which the view is presented. Since several windows may show the same document with its hierarchy of views, one and the same view may be visible several times simultaneously. This results in several frames for the same view simultaneously, and therefore in the need to update a view change in several frames.
In general, the reaction to a model modification happens in two steps. In the first step, the nature of the model's change is broadcast to all visible views, using the model broadcast mechanism of module Models. This causes every visible view to update its own state, if necessary. In the second step, every view which has changed its state uses the view broadcast mechanism of module Views, to notify all frames for this view. In fact, since frames are usually not extended, the view itself performs the update for each of its frames. This second broadcast step is normally invisible to the programmer, because he merely needs to determine the view's region which needs updating. The actual update of this region in each of its frames is done by the framework.
A view may behave differently depending on the model in which it is embedded, i.e. depending on its context. For this purpose, a variable of type Models.Context is carried by a view, as a link to its container.
For every user interaction, e.g. the press of a key, a view must be defined which should handle this interaction, i.e. a so-called focus. Oberon doesn't know which view is the current focus. Oberon only provides a strategy which decides which window is focus. Since a window may contain a hierarchy of views, a view which has received an interaction message - a controller message - must decide on its own whether it is the focus itself, or whether it contains another view which might be focus instead. In the former case, it handles the messages itself, in the latter case, it forwards the message to this view.
Every window contains a tree of frames. This tree corresponds to the visible views of the window. Every view may only draw inside its own borders, drawing outside of its borders must be prevented. Frames provide the necessary clipping facility. The management of the frame tree and of clipping is largely transparent to the view programmer.
CONST undefined
This value can be used to denote the width or height of a view as currently undefined.
CONST infinite
This value can be used to denote the width or height of a view as unlimited, or as too expensive to always be updated exactly.
CONST transparent
A view may be asked for its background color. In this case, the view may either return a Ports.Color value, or the value transparent. The latter value means that the view's container must find another source for a background color, i.e. for the color which is used to erase the background before the foreground is restored (use Update or UpdateIn to restore a view's area in all its frames). Transparency is useful if several views are superimposed on each other, which naturally occurs in a compound document.
CONST deep, shallow
There are two ways that a view can be copied: deep or shallow. This distinction arises from the fact that a view can carry two types of data: data that it owns completely, and data that it can share with other views. The most important example of the latter is the view's model, if it has one.
When a view is copied, it must be decided whether shareable state should actually be shared with the copy (shallow copy), or whether an independent copy of this state should be created (deep copy). For this purpose, a view's CopyModelFrom procedure has a Boolean parameter, which can take on one of the above constants.
CONST keepFrames, rebuildFrames
When part of a view's are must be restored (in every frame on it), there are two possible kinds of restoration: a frame may be kept as it is and only its contents be redrawn, or it may be rebuilt, i.e. newly allocated, set up, and redrawn. The latter is less efficient than the former, and only necessary if the following holds: the view must be a container, and the operation which changed the view might have modified a subview's bounding box (and thus invalidated its subframes). In the rare case where frames are extended, it could sometimes also become necessary to rebuild the frames on a view.
TYPE View
Interface, Extension
A view is a storable object which may contain a model, possibly maintains a scroll position in this model, and generates frames for its display when needed. A view can be regarded as a special editor, and advanced views (containers) are able to contain arbitrary other views as part of their editable data (i.e. of their model).
Views are allocated by specific view directories, e.g. TextViews.dir.
Views are used by commands which manipulate the visual presentation of data.
Views are extended for new kinds of data to be presented visually. Besides the implementation of new commands, the implementation of new view extensions is the central activity of Oberon programming.
Restore is the only procedure which necessarily must be extended in an extension of View.
Clone may be extended in order to return a narrowed result type, typically in extended interface types.
Internalize, Externalize, and CopyFrom must be extended in views which contain persistent mutable data.
ThisModel and CopyModelFrom must be extended in views which contain models.
ConsiderFocusRequestBy may be extended in container views.
Background must be extended in views which have a non-transparent background colors.
RestoreMarks and Neutralize must be extended in views which may contain marks like selections or carets.
HandleModelMsg must be extended in views which support partial view updates after a model change.
HandleViewMsg must be extended in views which support marks, or which don't use the delayed update mechanism for some other reason.
HandleCtrlMsg must be extended in editable views.
HandlePropMsg must be extended in views which support properties (not described in this documentation).
Init, InitContext, and NewFrame are usually not extended.
context-: Models.Context
The view's context links the view to its container. Communication between view and container occurs via the context. A context belongs (and is managed by) the container, but carried by the view.
PROCEDURE (v: View) Clone (): View
Default, Extension
Result type is narrowed to a view.
Clone is called by the view's container, before CopyFrom is called.
Clone is sometimes extended in order to yield a narrower result type, as is done here for (s: Store) Clone (): Store.
PROCEDURE (v: View) CopyFrom (source: View)
Extension
This procedure copies a view's non-shareable state, i.e. not its model.
CopyFrom calls v.Init.
CopyFrom is called by the view's container, at most once.
CopyFrom is extended to copy additional view-specific data.
Super call at the beginning is mandatory.
~v.init 20
source # NIL 21
source.init 22
v.init
PROCEDURE (v: View) ThisModel (): Models.Model
Default
Returns the model which v displays. The default implementation returns NIL.
ThisModel is called internally.
ThisModel is extended by views which contain models. Its result type may be narrowed.
This procedure copies a view's shareable data, in particular its model. v may either be assigned the same model as source (shallow copy), or an independent copy of it (deep copy).
CopyModelFrom is called internally.
CopyModelForm is extended by views which contain shareable mutable state, e.g. a model.
Super call at the beginning is mandatory.
PROCEDURE (v: View) Flush
Empty
A view which caches some data should implement the Flush procedure, which should clear the cache. This procedure may be called by the framework after a trap occurred, in order to reset a view to a defined state.
Flush is called by the framework under certain circumstances.
Flush is extended for views which may contain cached data.
A subview of v may request to become focus. Its container may or may not grant this request.
ConsiderFocusRequestBy is called by a subview.
ConsiderFocusRequestBy is extended in a container view.
PROCEDURE (v: View) Neutralize
Empty
This procedure should remove all marks that a view carries.
Neutralize is called by the framework.
Neutralize is extended by views which may contain marks.
PROCEDURE (v: View) NewFrame (host: Frame): Frame
Default
Generates a frame for the view. The frame in which this new frame will be contained is passed as parameter. It can be used to provide special host-frame or port-specific frame implementations. However, normally the default behavior of NewFrame is sufficient, which is to provide a generic Views.Frame as result.
NewFrame is called internally.
NewFrame is extended in views which need extended view frames.
host # NIL 20
result # NIL
result.view = NIL
PROCEDURE (v: View) Background (): Ports.Color
Default
This procedure returns the background color of the view. Its default implementation yields transparent.
Background is called internally.
Background is extended if a view needs a non-transparent background color.
Restore view v via frame f. Only the rectangle (l, t, r, b), which is given in universal coordinates, needs to be restored. Since drawing is clipped to this rectangle automatically, it is sometimes the best solution to simply restore the whole view's contents. However, often it is significantly faster to restore only the contents of the rectangle.
If necessary, the size of the view can be determined by calling v.context.GetSize.
Restore all marks (in particular any selection) of view v via frame f. Only the rectangle (l, t, r, b), which is given in universal coordinates, needs to be restored.
RestoreMarks is called internally.
RestoreMarks is extended in views which support any kind of marks, e.g. selection, caret, or focus marks.
HandleModelMsg is extended in views which support partial updates after a model modification.
msg.model # NIL 20
msg.model = v.ThisModel() 21
PROCEDURE (v: View) HandleViewMsg (f: Frame; VAR msg: Message)
Empty
Message handler for view messages.
HandleViewMsg is called internally.
HandleViewMsg is extended in views which support marks (e.g. selection marks), and in views which support different frame contents for the same view (a rare case).
f # NIL 20
f.view = v 21
v.context # NIL 22
msg.view = v OR msg.view = NIL 23
PROCEDURE (v: View) HandleCtrlMsg (f: Frame; VAR msg: CtrlMessage; VAR focus: View)
Property messages can be passed to a view via its HandlePropMsg procedure.
HandlePropMsg is called by the view's container.
HandlePropMsg is extended in views which support properties (not described here).
TYPE Alien
Extension
If the internalization of a view fails, either because its implementing module(s) cannot be loaded, or because it cancelled internalization e.g. because of a version conflict, an alien is produced instead (this happens in procedure ReadView). An alien is immutable and doesn't contain a model. It contains an alien store which can be inspected to determine the type of the alien, and the cause for it to be an alien.
Every container must be able to operate even if one or several of its embedded views are aliens. If the view's model is an alien store, the view may turn itself into an alien.
Aliens are allocated in ReadView.
Aliens are never extended.
store-: Stores.Alien
The alien store which has been generated by a Stores.Reader during internalization of the view.
TYPE Message
Interface, Extension
Base type of all view messages. Such messages are sent when a view's state has changed, in order to render the display consistent again. There may be several frames displaying the same view, such that every one of them needs to be updated.
Messages are sent by views when their states have changed and if they cannot use Oberon's delayed update mechanism. This is true mainly when drawing marks, e.g. selection marks.
Messages are extended to indicate what kind of update should be performed on a frame.
view-: View
The view which has changed. If view = NIL, all frames with the same domain are notified of the view change.
TYPE NotifyMsg
Extension
This message notifies all visible views about a change in an interactor's state (-> 5.9 Dialog).
NotifyMsg is sent by an interactor's Notify and CheckGuards procedures.
NotifyMsg is never extended.
id: LONGINT
Identification of the interactor or of one of its fields.
checkGuards: BOOLEAN
Determines whether controls (not described here) should check their guards.
TYPE Frame
Extension
Extension of a Ports.Frame. All input and output operations of a view pass through a frame. A frame manages the whole layout of views on a port, including clipping. Model and view messages are broadcast along frame trees. A frame tree's internal structure is hidden. Frames are volatile objects, they are allocated and released by Oberon whenever ncecessary, e.g. when the frame's window is zoomed. Thus they cannot be used to carry application-specific state, except for caches.
Frames are allocated by a view's NewFrame procedure.
Frames are managed internally, and passed as parameters to view procedures whenever necessary.
Frames are sufficient for most purposes, and thus rarely extended.
l-, t-, r-, b-: LONGINT 0 <= l <= r & 0 <= t <= b
The visible area of the view in this frame.
view-: View view # NIL
The frame's view.
target-, front-: BOOLEAN
Flags which tell whether the frame is part of the target or front window, or both if the front window is target as well.
PROCEDURE (f: Frame) Close
Empty
Closes the frame.
Close calls ConnectTo(NIL).
Close is used and extended internally.
f.view = NIL
f.rider = NIL
TYPE RootFrame
This type is used internally.
flags-: SET
Window-specific flags. Reserved for future use.
TYPE PropMessage
Interface, Extension
Use its alias Properties.Message instead (properties are not described here).
TYPE CtrlMessage
Interface
Base type of all controller messages. Use its alias Controllers.Message instead.
TYPE CtrlMsgHandler
Used internally.
TYPE Title
Type for view titles, e.g. in windows.
PROCEDURE Broadcast (v: View; VAR msg: Message)
Broadcast msg for view. Before broadcasting, parameter v is assigned to the message's view-Field. The actual broadcast only takes place if v.domain # NIL.
Broadcast is called by a view whenever its state has changed and the delayed restore mechanism is not sufficient, e.g. to update frame-specific marks.
v # NIL 20
msg.view = v
PROCEDURE Domaincast (domain: Domains.Domain; VAR msg: Message)
Broadcasts msg inside domain.
PROCEDURE BeginModification (v: View)
PROCEDURE EndModification (v: View)
PROCEDURE BeginScript (v: View; name: Domains.OpName; VAR script: Domains.Operation)
PROCEDURE Do (v: View; name: Domains.OpName; op: Domains.Operation)
PROCEDURE LastOp (v: View): Domains.Operation
PROCEDURE Bunch (v: View)
PROCEDURE StopBunching (v: View)
These procedures handle modifications of a view. They are used in the same way as their model counterparts in module Models (-> 5.6 Models).
PROCEDURE Update (v: View)
Causes view v to be restored, in all frames displaying v. The update occurs delayed, after the currently executing command has terminated.
v # NIL 20
PROCEDURE UpdateIn (v: View; l, t, r, b: LONGINT)
Causes rectangle (l, t, r, b) of view v to be restored, in all frames displaying v. The update occurs delayed, after the currently executing command has terminated.
v # NIL 20
PROCEDURE ReadView (VAR rd: Stores.Reader; VAR v: View)
Reads view v, using reader rd. If internalization is not possible, an alien view is returned.
If view has no corresponding embedded frame in host, Install allocates and installs a new one for it, otherwise the existing frame is kept. Parameters x and y give the position of the view's top-left corner relative to the container view's (i.e. host.view) top-left corner. The frame ordering can be influenced by passing a view level at which view lies logically. Levels need not be unique (pass 0 if you don't care, e.g. if you never have overlapping frames). A frame always lies "above" other frames with smaller levels. Parameter focus tells whether the frame is part of the focus path.
This procedure looks up a file, reads in the document in this file, and then returns the root view of this document. If the file is already opened in a window, the root view of this window's document is returned.
Saves the document in which view is embedded in a file.
view # NIL 20
view.init 21
loc # NIL 22
name # "" 23
PROCEDURE Open (view: View; loc: Files.Locator; name: Files.Name)
Open view in a new window. (loc, name) determines the file associated with view, if there is any.
view # NIL 20
(loc = NIL) = (name = "") 21
PROCEDURE OpenAux (view: View; title: Title)
Opens view in an auxiliary window with title title.
view # NIL 20
title # "" 21
PROCEDURE Deposit (view: View)
Deposit a view for later use, typically for opening it in a window, or for pasting it to the focus.
Deposit is used only by allocation commands, i.e. commands which allocate and then deposit a concrete view type.
view # NIL 20
PROCEDURE RestoreDomain (domain: Domains.Domain)
This procedures forces a restoration of all update regions on views of domain.
Normally, the display is updated in a delayed fashion, i.e. an update region is built for all invalid view areas (using Update and UpdateIn), and the display update according to this region is performed when the framework is idle, i.e. between commands. However, sometimes it is necessary to enforce a display update during a command, for which this procedure can be used. The need for enforced update comes from scrolling: if a view should be scrolled, the effect of scrolling should become immediately visible.
PROCEDURE Scroll (v: View; dx, dy: LONGINT)
Scroll the contents of each frame on v by (dx, dy).